﻿using System.Collections.Generic;
using System.Reflection;
using System.Web.UI;

namespace ViewStatePropertyTest
{
    public class ViewStatePropertyBasePage : Page
    {
        private IDictionary<PropertyInfo, ViewStateProperty[]> ViewStateProperties;

        private void InitViewStateProperties()
        {
            var properties = this.GetType()
                .GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);

            ViewStateProperties = new Dictionary<PropertyInfo, ViewStateProperty[]>(properties.Length);
            foreach (var property in properties)
            {
                var attibutes = property.GetCustomAttributes(typeof(ViewStateProperty), true);
                if (null != attibutes && attibutes.Length > 0)
                    ViewStateProperties.Add(property, attibutes as ViewStateProperty[]);
            }
        }

        protected ViewStatePropertyBasePage()
        {
            InitViewStateProperties();
        }

        private string GetViewStatePropertyName(PropertyInfo propertyInfo, ViewStateProperty[] attributes)
        {
            if (!string.IsNullOrEmpty(attributes[0].Key))
                return attributes[0].Key;

            return propertyInfo.Name;
        }

        protected override void LoadViewState(object savedState)
        {
            base.LoadViewState(savedState);

            if (null == ViewStateProperties || 0 == ViewStateProperties.Count)
                return;

            foreach (var property in ViewStateProperties)
            {
                var sPropertyName = GetViewStatePropertyName(property.Key, property.Value);
                var oPropertyValue = this.ViewState[sPropertyName];
                if (null != oPropertyValue)
                    property.Key.SetValue(this, oPropertyValue, null);
            }
        }

        protected override object SaveViewState()
        {
            if (null == ViewStateProperties || 0 == ViewStateProperties.Count)
                return base.SaveViewState();

            foreach (var property in ViewStateProperties)
            {
                var oPropertyValue = property.Key.GetValue(this, null);
                var sPropertyName = GetViewStatePropertyName(property.Key, property.Value);
                ViewState[sPropertyName] = oPropertyValue;
            }

            return base.SaveViewState();
        }
    }
}
